package empe;

/**
 * Classe que contem a funcao static main e que inicializa todo o processo
 * de importacao xml e simulacao
 */
public class Simulacao {

	private static Cap cap;
	private static Lista_individuo lista_individuo;
	private static XMLimport xml;
	private static int tactual;
	private static int instante_print;
	
	/**
	 * Inicia o importador xml e simulacao
	 * @param args ficheiro xml de entrada
	 */
	public static void main(String[] args) {
		
		try{
			xml = new XMLimport(args[0]);
		} catch (Exception e)
		{
			System.out.print(e);
			System.exit(2);
		}
		
		xml.actualizar_controlo();
		
		cap=new Cap();
		
		lista_individuo= new Lista_individuo(cap);
		
		Controlo.lista_individuo=lista_individuo;
		
		lista_individuo.init_populacao();
		
		tactual=0;
		
		simulacao();
	}
	
	
	
	
	
	/**
	 * Simula todos os eventos da cap ate esta lhe devolver evento nulo ou 
	 * que lhe devolva um instante de tempo igual a tempo maximo de simulacao
	 */
	private static void simulacao()
	{
		int num_eventos = 0;
		int intervalo=(int)Math.round(Controlo.ler_tmax()/20.0);
		instante_print=0;
		
		
		imprime_consola(num_eventos);
		//Ciclo de simulação
		for(Evento evento=cap.retira_prox_elemento(); evento!=null; evento=cap.retira_prox_elemento())
		{
			
			Evento ev = evento.simular();
			if(ev != null)
				cap.insere_elemento(ev); /*reinsere reproducoes e mutacoes*/
			
			num_eventos++;

			if(tactual != cap.tempo_prox_evento())
			{
				tactual=cap.tempo_prox_evento();
				
				if(tactual==Controlo.ler_tmax()) break;
				while(lista_individuo.ler_populacao_actual()>Controlo.ler_populacao_max())
				{
					lista_individuo.epidemia();
				}
				
				if(tactual>=intervalo+instante_print & tactual!=Controlo.ler_tmax()) {
					instante_print+=intervalo;
					imprime_consola(num_eventos);
					
				}							
			}			
		}
		instante_print=Controlo.ler_tmax();
		imprime_consola(num_eventos);
		//lista_individuo.printar();
		//System.out.print("\n fim!");
		
	}
	
	/**
	 * Imprime estatisticas da simulacao
	 * @param num_eventos numero de eventos simulados ate ao instante actual
	 */
	private static void imprime_consola(int num_eventos) {
		
		Individuo melhor = lista_individuo.ler_best();
		
		System.out.print("\nInstante actual:              "+instante_print);
		System.out.print("\nNúmero de eventos realizados: "+num_eventos);
		System.out.print("\nDimensão da população:        "+lista_individuo.ler_populacao_actual());
		System.out.print("\nNúmero de epidemias:          "+lista_individuo.ler_num_epidemias());
		System.out.print("\nTempo de execução em paralelo:"+melhor.calc_temp_exec());
		System.out.print("\nConforto:                     "+melhor.ler_conforto());
		System.out.print("\n\n");
	}

}
